﻿#include "gamecontrol.h"

#include <QTimer>
#include <QDebug>
#include <QRandomGenerator>
GameControl::GameControl(QObject *parent) : QObject(parent)
{
    //m_betRecord.times=0;
}

void GameControl::playerInit()
{
    //玩家实例化
    m_robotLeft=new Robot("机器人A",this);
    m_roborRight=new Robot("机器人B",this);
    m_userPlayer=new UserPlayer("我自己",this);
    //设置分数
    m_robotLeft->setScore(0);
    m_roborRight->setScore(0);
    m_userPlayer->setScore(0);

    //头像位置初始化
    m_robotLeft->setDirection(Player::left);
    m_roborRight->setDirection(Player::right);
    m_userPlayer->setDirection(Player::right);

    //性别
    Player::Sex sex;
    sex=(Player::Sex)QRandomGenerator::global()->bounded(2);
    m_robotLeft->setSex(sex);

    sex=(Player::Sex)QRandomGenerator::global()->bounded(2);
    m_roborRight->setSex(sex);

    sex=(Player::Sex)QRandomGenerator::global()->bounded(2);
    m_userPlayer->setSex(sex);

    //出牌顺序
    m_userPlayer->setPrevPlayer(m_roborRight);
    m_userPlayer->setNextPlayer(m_robotLeft);

    m_roborRight->setPrevPlayer(m_robotLeft);
    m_roborRight->setNextPlayer(m_userPlayer);

    m_robotLeft->setPrevPlayer(m_userPlayer);
    m_robotLeft->setNextPlayer(m_roborRight);

    m_curPlayer=m_userPlayer;

    m_betRecord.point=0;

    //处理玩家发出的叫地主信号
    connect(m_userPlayer,&UserPlayer::notifyGrabLordBet,this,&GameControl::onGrabBet);
    connect(m_robotLeft,&UserPlayer::notifyGrabLordBet,this,&GameControl::onGrabBet);
    connect(m_roborRight,&UserPlayer::notifyGrabLordBet,this,&GameControl::onGrabBet);
    //通知控制类
    connect(m_userPlayer,&UserPlayer::notifyPlayhand,this,&GameControl::onPlayhand);
    connect(m_robotLeft,&Robot::notifyPlayhand,this,&GameControl::onPlayhand);
    connect(m_roborRight,&Robot::notifyPlayhand,this,&GameControl::onPlayhand);

    //通知玩家存储出牌玩家和牌
    connect(this,&GameControl::pendingInfo,m_userPlayer,&UserPlayer::storePendingInfo);
    connect(this,&GameControl::pendingInfo,m_roborRight,&Robot::storePendingInfo);
    connect(this,&GameControl::pendingInfo,m_robotLeft,&Robot::storePendingInfo);

}

Robot *GameControl::getLeftRobot()
{
    return m_robotLeft;
}

Robot *GameControl::getRightRobot()
{
    return m_roborRight;
}

UserPlayer *GameControl::getUserPlayer()
{
    return m_userPlayer;
}

void GameControl::setCurPlayer(Player *player)
{
    m_curPlayer=player;
}

Player *GameControl::getCurPlayer()
{
    return m_curPlayer;
}

Player *GameControl::getPendPlayer()
{
    return m_pendPlayer;
}

Cards GameControl::getPendCards()
{
    return m_pendCards;
}

void GameControl::initAllCards()
{
    m_allCards.clear();
    for(int p=Card::Card_Begin+1;p<Card::Card_SJ;p++)
    {
        for(int s=Card::Suit_Begin+1;s<Card::Suit_End;s++)
        {
            Card newCard((Card::CardPoint)p,(Card::CardSuit)s);
            m_allCards.add(newCard);
        }
    }
    m_allCards.add(Card(Card::Card_SJ,Card::Suit_Begin));
    m_allCards.add(Card(Card::Card_BJ,Card::Suit_Begin));
}

Card GameControl::takeOneCard()
{
    return m_allCards.takeRandCard();
}

Cards GameControl::getSurplusCards()
{
    return m_allCards;
}

void GameControl::resetCardData()
{
    initAllCards();
    m_robotLeft->clearCards();
    m_roborRight->clearCards();
    m_userPlayer->clearCards();

    m_pendPlayer=NULL;
    m_pendCards.clear();
}

void GameControl::startLordCard()
{
    m_curPlayer->prepareCallLord();
    emit playerStatusChanged(m_curPlayer,ThinkingForCallLord);
}


void GameControl::becomeLord(Player *player, int bet)
{

    player->setRole(Player::lord);

    player->getPrevPlayer()->setRole(Player::farmer);
    player->getNextPlayer()->setRole(Player::farmer);

    m_curPlayer=player;
    m_curBet=bet;
    player->storeDispatchCard(m_allCards);


    QTimer::singleShot(200,this,[=](){
        emit gameStatusChanged(PlayingHnad);
        emit playerStatusChanged(player,ThinkingForPlayHand);
    });
    m_curPlayer->preparePlayHand();
}

void GameControl::clearPlayerScre()
{
    m_userPlayer->setScore(0);
    m_robotLeft->setScore(0);
    m_roborRight->setScore(0);
}

void GameControl::onGrabBet(Player *player, int point)
{
    if(point==0||m_betRecord.point>=point)
    {
        emit notifyGrabLordBet(player,0,false);
    }
    else if(point>0&&m_betRecord.point==0)
    {
        //说明该玩家是第一个抢地主的人
        emit notifyGrabLordBet(player,point,true);
    }
    else {
        //该玩家是第二个或第三个抢地主的人
        emit notifyGrabLordBet(player,point,false);
    }
    //判断是否叫了3分
    if(point==3)
    {
        becomeLord(player,point);
        //清空数据
        m_betRecord.reset();
        return;
    }
    //下注不够3分，对玩家的分数进行比较，分数高的是地主
    if(m_betRecord.point<point)
    {
        m_betRecord.player=player;
        m_betRecord.point=point;
    }
    m_betRecord.times+=1;
    if(m_betRecord.times==3)
    {
        if(m_betRecord.point==0)
        {
            //发送信号要求重新洗牌
            emit gameStatusChanged(DispatchCard);
        }
        else
        {
            //成为地主
            becomeLord(m_betRecord.player,m_betRecord.point);
        }
        m_betRecord.reset();
        return;
    }
    //切换玩家，通知下一个玩家继续抢地主
    m_curPlayer=player->getNextPlayer();
    emit playerStatusChanged(m_curPlayer,ThinkingForCallLord);
    m_curPlayer->prepareCallLord();
}

int GameControl::getPlayerMaxBet()
{
    return m_betRecord.point;

}

void GameControl::onPlayhand(Player *player, Cards cards)
{
    //将玩家出牌信号转发给主界面
    emit notifyPlayhand(player,cards);
    //判断打出的牌是不是空的
    if(!cards.isEmpty())
    {
        m_pendPlayer=player;
        m_pendCards=cards;
        emit pendingInfo(player,cards);
    }
    //如果有炸弹，低分翻倍
    PlayHand::HandType type = PlayHand(cards).getHandType();
    if(type==PlayHand::Hand_Bomb||type==PlayHand::Hand_Bomb_Jokers)
    {
        m_curBet*=2;
    }
    //如果玩家的牌出完了，计算总分
    if(player->getCards().cardcount()==0)
    {
        Player* prev=player->getPrevPlayer();
        Player* next=player->getNextPlayer();
        if(player->getRole()==Player::lord)
        {
            player->setScore(player->getScore()+m_curBet*2);
            prev->setScore(prev->getScore()-m_curBet);
            next->setScore(next->getScore()-m_curBet);
            player->setWin(true);
            prev->setWin(false);
            next->setWin(false);
        }
        else
        {
            player->setScore(player->getScore()+m_curBet);
            player->setWin(true);
            if(prev->getRole()==Player::lord)
            {
                prev->setScore(prev->getScore()-m_curBet*2);
                next->setScore(next->getScore()+m_curBet);
                prev->setWin(false);
                next->setWin(true);
            }
            else
            {
                prev->setScore(prev->getScore()+m_curBet);
                next->setScore(next->getScore()-2*m_curBet);
                prev->setWin(true);
                next->setWin(false);

            }
        }
        emit playerStatusChanged(player,GameControl::winning);
        return;
    }
    else//牌没有出完
    {
        m_curPlayer=player->getNextPlayer();
        m_curPlayer->preparePlayHand();
        emit playerStatusChanged(m_curPlayer,GameControl::ThinkingForPlayHand);
    }
}
